﻿using Mysoft.Map.Extensions.DAL;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Mysoft.QuickCode.DbExpressionExtensions
{
    /// <summary>
    /// 数据库对象集合，数据库对象操作的基本单元，类似于“表”的概念。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class EntityTable<T>
        where T : class
    {
        private string tableName = string.Empty;

        /// <summary>
        /// 对象属性与数据库表字段的映射关系
        /// </summary>
        internal Dictionary<string, string> PropertyToFileds = new Dictionary<string, string>();

        /// <summary>
        /// 标记为是否已经处理过排序
        /// </summary>
        internal bool Ordered = false;

        /// <summary>
        /// 参数化的SQL语句
        /// </summary>
        public StringBuilder CommandText { set; get; }

        /// <summary>
        /// 参数化SQL语句中需要的参数值字典
        /// </summary>
        public Stack<KeyValuePair<string, object>> Parameters { set; get; }

        public EntityTable()
        {
            this.CommandText = new StringBuilder();
            this.Parameters = new Stack<KeyValuePair<string, object>>();

            //取所有属性对应的表字段映射
            PropertyInfo[] props = typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
            foreach (PropertyInfo p in props)
            {
                DataColumnAttribute attr = p.GetCustomAttributes(typeof(DataColumnAttribute), false).FirstOrDefault() as DataColumnAttribute;
                PropertyToFileds.Add(p.Name, (attr == null || string.IsNullOrEmpty(attr.Alias)) ? p.Name : attr.Alias);
            }
        }

        /// <summary>
        /// 获取一个对象的实例
        /// </summary>
        public static EntityTable<T> Instance
        {
            get
            {
                return new EntityTable<T>();
            }
        }

        /// <summary>
        /// 获取对象对应的数据表名称
        /// </summary>
        /// <returns></returns>
        public string GetTableName()
        {
            if (string.IsNullOrEmpty(tableName))
            {
                Type eType = typeof(T);
                DataEntityAttribute attr = eType.GetCustomAttributes(typeof(DataEntityAttribute), false).FirstOrDefault() as DataEntityAttribute;
                //获取表名称自定义属性
                this.tableName = (null == attr || string.IsNullOrEmpty(attr.Alias)) ? eType.Name : attr.Alias;
            }
            //有自定义表名称属性，则取自定义表名称，否则直接取对象名称作为表名称
            return tableName;
        }

        /// <summary>
        /// 获取对象的查询为参数化的CPQuery对象
        /// </summary>
        /// <returns></returns> 
        public CPQuery AsQuery()
        {
            List<SqlParameter> paramList = new List<SqlParameter>();

            foreach (KeyValuePair<string, object> kv in this.Parameters.Reverse())
            {
                paramList.Add(new SqlParameter(kv.Key, kv.Value));
            }
            SqlParameter[] cloneSqlParamList = paramList.Select(m => ((ICloneable)m).Clone() as SqlParameter).ToArray();
            return CPQuery.From(this.CommandText.ToString(), cloneSqlParamList);
        }
    }
}
